diff options
| author | Fuwn <[email protected]> | 2024-10-06 01:41:44 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-10-06 01:41:44 -0700 |
| commit | a84d9c9f47c7cd1b345d0283bef9f211a9727893 (patch) | |
| tree | 554827840b67e8a0068e707fad973a8780f47957 /src/routes/user/[user]/badges | |
| parent | feat(graphql): add subtitles (diff) | |
| download | due.moe-a84d9c9f47c7cd1b345d0283bef9f211a9727893.tar.xz due.moe-a84d9c9f47c7cd1b345d0283bef9f211a9727893.zip | |
feat(badges): move badge operations to graphql
Diffstat (limited to 'src/routes/user/[user]/badges')
| -rw-r--r-- | src/routes/user/[user]/badges/+page.gql | 17 | ||||
| -rw-r--r-- | src/routes/user/[user]/badges/+page.server.ts | 5 | ||||
| -rw-r--r-- | src/routes/user/[user]/badges/+page.svelte | 853 | ||||
| -rw-r--r-- | src/routes/user/[user]/badges/+page.ts | 20 |
4 files changed, 495 insertions, 400 deletions
diff --git a/src/routes/user/[user]/badges/+page.gql b/src/routes/user/[user]/badges/+page.gql new file mode 100644 index 00000000..44c35bd8 --- /dev/null +++ b/src/routes/user/[user]/badges/+page.gql @@ -0,0 +1,17 @@ +query UserBadges($id: Int!) { + User(id: $id) { + badges { + post + image + description + id + time + category + hidden + source + designer + shadow_hidden + click_count + } + } +} diff --git a/src/routes/user/[user]/badges/+page.server.ts b/src/routes/user/[user]/badges/+page.server.ts deleted file mode 100644 index f18892a7..00000000 --- a/src/routes/user/[user]/badges/+page.server.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const load = async ({ params }) => { - return { - username: params.user - }; -}; diff --git a/src/routes/user/[user]/badges/+page.svelte b/src/routes/user/[user]/badges/+page.svelte index 499233ce..c4d48454 100644 --- a/src/routes/user/[user]/badges/+page.svelte +++ b/src/routes/user/[user]/badges/+page.svelte @@ -3,7 +3,6 @@ import { userIdentity } from '$lib/Data/AniList/identity'; import { user, type User } from '$lib/Data/AniList/user'; import type { Badge } from '$lib/Database/SB/User/badges'; - // import { domToBlob } from 'modern-screenshot'; import { onDestroy, onMount } from 'svelte'; import HeadTitle from '$lib/Home/HeadTitle.svelte'; import { databaseTimeToDate, dateToInputTime, inputTimeToDatabaseTime } from '$lib/Utility/time'; @@ -20,16 +19,118 @@ import { page } from '$app/stores'; import type { UserPreferences } from '$lib/Database/SB/User/preferences'; import { browser } from '$app/environment'; - // import { io } from 'socket.io-client'; import BadgePreview from '$lib/User/BadgeWall/BadgePreview.svelte'; import authorisedJson from '$lib/Data/Static/authorised.json'; import identity from '$stores/identity'; import '$lib/User/BadgeWall/badges.css'; import Badges from '$lib/User/BadgeWall/Badges.svelte'; import type { IndexedBadge } from '$lib/User/BadgeWall/badge'; + import { graphql } from '$houdini'; export let data; + $: ({ UserBadges } = data); + + const updateBadgeQuery = graphql(` + mutation UpdateBadge( + $id: Int + $post: String + $image: String + $description: String + $time: String + $category: String + $hidden: Boolean + $source: String + $designer: String + ) { + updateBadge( + id: $id + post: $post + image: $image + description: $description + time: $time + category: $category + hidden: $hidden + source: $source + designer: $designer + ) { + post + image + description + id + time + category + hidden + source + designer + shadow_hidden + click_count + } + } + `); + + const pruneBadgesQuery = graphql(` + mutation PruneUserBadges { + pruneUserBadges { + post + image + description + id + time + category + hidden + source + designer + shadow_hidden + click_count + } + } + `); + + const hideCategoryQuery = graphql(` + mutation HideCategory($category: String) { + hideBadge(category: $category) { + post + image + description + id + time + category + hidden + source + designer + shadow_hidden + click_count + } + } + `); + + const deleteBadgeQuery = graphql(` + mutation DeleteBadge($id: Int!) { + deleteBadge(id: $id) { + post + image + description + id + time + category + hidden + source + designer + shadow_hidden + click_count + } + } + `); + + const shadowHideBadgeQuery = graphql(` + mutation ShadowHideBadge($id: Int!, $state: Boolean) { + shadowHideBadge(id: $id, state: $state) { + id + } + } + `); + interface ImportImage { link?: string; image: string; @@ -40,7 +141,6 @@ let currentUserIdentity: ReturnType<typeof userIdentity>; let error: null | string; // const socket = io(); - let badgesPromise: Promise<Response>; let awcPromise: Promise<Response>; // let dark = true; // let transparent = false; @@ -67,16 +167,12 @@ type GroupedBadges = { [key: string]: IndexedBadge[] }; - const getBadges = () => (badgesPromise = fetch(root(`/api/badges?id=${badger.id}`))); - const setShadowHide = () => - fetch(`/api/badges?shadowHide=${badger.id}`, { - method: 'PUT' - }).then(getBadges); + shadowHideBadgeQuery.mutate({ + id: badger.id as number + }); onMount(async () => { - // socket.on('badges', (message) => (badges = message)); - if (browser && localStorage.getItem('badgeWallNoticeDismissed')) noticeDismissed = true; badger = isId @@ -92,7 +188,6 @@ return; } - badgesPromise = fetch(root(`/api/badges?id=${badger.id}`)); awcPromise = fetch(proxy(`https://awc.moe/challenger/${badger.name}`)); preferences = await (await fetch(root(`/api/preferences?id=${badger.id}`))).json(); @@ -118,8 +213,6 @@ if (data.user && !isId) { currentUserIdentity = userIdentity(data.user); - - // socket.emit('badges', data.user); } else { currentUserIdentity = new Promise((resolve) => resolve({ @@ -181,32 +274,27 @@ return; } - badgesPromise = fetch( - `/api/badges?image=${encodeURIComponent(imageURL.value)}&post=${encodeURIComponent( - activityURL.value || '#' - )}${ - description.value.length > 0 ? `&description=${encodeURIComponent(description.value)}` : '' - }${category.value.length > 0 ? `&category=${encodeURIComponent(category.value)}` : ''}${ - time.valueAsDate - ? `&time=${encodeURIComponent(inputTimeToDatabaseTime(time.valueAsDate))}` - : '' - }${ - selectedBadge && selectedBadge.id ? `&update=${encodeURIComponent(selectedBadge.id)}` : '' - }&hidden=${hidden.value === 'Hidden'}${ - source.value.length > 0 ? `&source=${encodeURIComponent(source.value)}` : '' - }${designer.value.length > 0 ? `&designer=${encodeURIComponent(designer.value)}` : ''}`, - { - method: 'PUT' - } - ); - - error = null; - imageURL.value = ''; - activityURL.value = ''; - description.value = ''; - category.value = ''; - hidden.value = 'Shown'; - selectedBadge = undefined; + updateBadgeQuery + .mutate({ + id: selectedBadge?.id, + image: imageURL.value, + post: activityURL.value || '#', + description: description.value, + category: category.value, + time: time.valueAsDate ? inputTimeToDatabaseTime(time.valueAsDate) : undefined, + hidden: hidden.value === 'Hidden', + source: source.value, + designer: designer.value + }) + .then(() => { + error = null; + imageURL.value = ''; + activityURL.value = ''; + description.value = ''; + category.value = ''; + hidden.value = 'Shown'; + selectedBadge = undefined; + }); }; const removeAllBadges = () => { @@ -223,9 +311,8 @@ } selectedBadge = undefined; - badgesPromise = fetch(root(`/api/badges?prune=true`), { - method: 'DELETE' - }); + + pruneBadgesQuery.mutate(null).then(); }; const removeBadge = (badge: Badge) => { @@ -245,9 +332,12 @@ (document.querySelector(`#badge-${badge.id}`) as HTMLAnchorElement).style.display = 'none'; selectedBadge = undefined; - badgesPromise = fetch(root(`/api/badges?id=${badge.id}`), { - method: 'DELETE' - }); + + deleteBadgeQuery + .mutate({ + id: badge.id + }) + .then(); }; const groupBadges = (badges: IndexedBadge[]) => { @@ -369,7 +459,7 @@ }); const migrateCategory = () => { - badgesPromise = fetch( + fetch( `/api/badges?migrate=true&original=${encodeURIComponent( (document.querySelector('#migrate_original') as HTMLInputElement).value )}&new=${encodeURIComponent( @@ -378,22 +468,15 @@ { method: 'PUT' } - ); - - migrateMode = false; + ).then(() => (migrateMode = false)); }; const hideCategory = () => { - badgesPromise = fetch( - `/api/badges?hide=true&category=${encodeURIComponent( - (document.querySelector('#category_hide') as HTMLInputElement).value - )}`, - { - method: 'PUT' - } - ); - - hideMode = false; + hideCategoryQuery + .mutate({ + category: (document.querySelector('#category_hide') as HTMLInputElement).value + }) + .then(() => (hideMode = false)); }; // const exportBadges = (groupedBadges: [string, Badge[]][]) => { @@ -455,12 +538,12 @@ const shadowHideBadge = () => { if (!selectedBadge && !authorised) return; - badgesPromise = fetch( - `/api/badges?shadowHideBadge=${selectedBadge?.id}&status=${selectedBadge?.shadow_hidden}&id=${badger.id}`, - { - method: 'PUT' - } - ); + shadowHideBadgeQuery + .mutate({ + id: badger.id as number, + state: selectedBadge?.shadow_hidden as boolean + }) + .then(); }; </script> @@ -478,376 +561,356 @@ {:then identity} {@const isOwner = identity && (isId ? identity.id : identity.name) === data.username} - {#await badgesPromise} + {#if $UserBadges.fetching || !$UserBadges.data} <Message message="Loading badges ..." /> <Skeleton grid={true} count={100} width="150px" height="170px" /> - {:then badgesResponse} - {#if badgesResponse} - {#await badgesResponse.clone().json()} - <Message message="Parsing badges ..." /> - - <Skeleton grid={true} count={100} width="150px" height="170px" /> - {:then ungroupedBadgesAny} - {@const ungroupedBadges = castBadgesToIndexedBadges(ungroupedBadgesAny)} - {@const isBadgeSelected = - selectedBadge && - selectedBadge !== undefined && - selectedBadge.image && - selectedBadge.image !== undefined && - !editMode} - - <div id="badges"> - {#if preferences && !preferences.hide_awc_badges} - <AWC {awcPromise} {categoryFilter} {isOwner} {preferences} /> + {:else} + {@const ungroupedBadges = castBadgesToIndexedBadges($UserBadges.data.User.badges)} + {@const isBadgeSelected = + selectedBadge && + selectedBadge !== undefined && + selectedBadge.image && + selectedBadge.image !== undefined && + !editMode} + + <div id="badges"> + {#if preferences && !preferences.hide_awc_badges} + <AWC {awcPromise} {categoryFilter} {isOwner} {preferences} /> + {/if} + + {#if ungroupedBadges === null} + <Message message="Loading badges ..." /> + + <Skeleton grid={true} count={10} width="150px" height="170px" /> + {:else} + {@const groupedBadges = Object.entries( + groupBadges(removeHiddenBadges(isOwner, ungroupedBadges)) + )} + + {#if isOwner || authorised} + {@const shadowHiddenCount = ungroupedBadges.filter( + (badge) => badge.shadow_hidden + ).length} + {@const shadowHidden = shadowHiddenCount > 0} + + {#if shadowHidden} + <div class="card"> + <b>Notice:</b> The Badge Wall overseer system has detected badges containing + AI-generated material on your wall. {shadowHiddenCount} of your badges have been shadow + hidden. + <p /> + You may use the "Un-shadow Hide Badges" button to unhide these badges, from where you + will be required to use the hide feature to hide these badges from the public, while + allowing them to stay visible to you as the account holder. + </div> + {:else if !noticeDismissed} + <div class="card"> + <b>Notice:</b> AniList has begun purging outbound links which contain AI-generated + material, this includes Badge Wall. If you have collected badges with AI-generated + elements, kindly use the hide feature to hide these badges from the public, while + allowing them to stay visible to you as the account holder. + <p /> + Failure to comply with this request at your earliest convenience will result in the hiding + of all badges from your Badge Wall. + <p /> + <button + on:click={() => { + noticeDismissed = true; + + localStorage.setItem('badgeWallNoticeDismissed', 'true'); + }} + > + Dismiss + </button> + </div> {/if} - {#if ungroupedBadges === null} - <Message message="Loading badges ..." /> + <p /> - <Skeleton grid={true} count={10} width="150px" height="170px" /> - {:else} - {@const groupedBadges = Object.entries( - groupBadges(removeHiddenBadges(isOwner, ungroupedBadges)) - )} + <div class="card"> + {#if authorised} + <button on:click={setShadowHide}>Shadow Hide Badges</button> + {/if} - {#if isOwner || authorised} - {@const shadowHiddenCount = ungroupedBadges.filter( - (badge) => badge.shadow_hidden - ).length} - {@const shadowHidden = shadowHiddenCount > 0} + {#if isOwner && authorised} + <span style="margin: 0 0.625rem;">•</span> + {/if} + + {#if isOwner} + <button + on:click={() => { + selectedBadge = undefined; + editMode = !editMode; + }} + > + {editMode + ? $locale().user.badges.editMode.disable + : $locale().user.badges.editMode.enable} + </button> + <span style="margin: 0 0.625rem;">•</span> + <button + on:click={() => { + selectedBadge = undefined; + importMode = !importMode; + }} + > + {importMode + ? $locale().user.badges.importMode.disable + : $locale().user.badges.importMode.enable} + </button> + <span style="margin: 0 0.625rem;">•</span> + <button + on:click={() => { + selectedBadge = undefined; + migrateMode = !migrateMode; + }} + > + Migrate Category + </button> + <span style="margin: 0 0.625rem;">•</span> + <button + on:click={() => { + selectedBadge = undefined; + hideMode = !hideMode; + }} + > + Hide Category + </button> + <!-- <!-- <span style="margin: 0 0.625rem;">•</span> --> + <!-- <button on:click={() => exportBadges(groupedBadges)}>Export Badges</button> --> {#if shadowHidden} - <div class="card"> - <b>Notice:</b> The Badge Wall overseer system has detected badges containing - AI-generated material on your wall. {shadowHiddenCount} of your badges have been - shadow hidden. - <p /> - You may use the "Un-shadow Hide Badges" button to unhide these badges, from where - you will be required to use the hide feature to hide these badges from the public, - while allowing them to stay visible to you as the account holder. - </div> - {:else if !noticeDismissed} - <div class="card"> - <b>Notice:</b> AniList has begun purging outbound links which contain - AI-generated material, this includes Badge Wall. If you have collected badges - with AI-generated elements, kindly use the hide feature to hide these badges - from the public, while allowing them to stay visible to you as the account - holder. - <p /> - Failure to comply with this request at your earliest convenience will result in the - hiding of all badges from your Badge Wall. - <p /> - <button - on:click={() => { - noticeDismissed = true; - - localStorage.setItem('badgeWallNoticeDismissed', 'true'); - }} - > - Dismiss - </button> - </div> + <span style="margin: 0 0.625rem;">•</span> + <button on:click={setShadowHide}>Un-shadow Hide Badges</button> {/if} - <p /> - - <div class="card"> - {#if authorised} - <button on:click={setShadowHide}>Shadow Hide Badges</button> - {/if} - - {#if isOwner && authorised} - <span style="margin: 0 0.625rem;">•</span> - {/if} - - {#if isOwner} - <button - on:click={() => { - selectedBadge = undefined; - editMode = !editMode; - }} - > - {editMode - ? $locale().user.badges.editMode.disable - : $locale().user.badges.editMode.enable} - </button> - <span style="margin: 0 0.625rem;">•</span> - <button - on:click={() => { - selectedBadge = undefined; - importMode = !importMode; - }} - > - {importMode - ? $locale().user.badges.importMode.disable - : $locale().user.badges.importMode.enable} - </button> - <span style="margin: 0 0.625rem;">•</span> - <button - on:click={() => { - selectedBadge = undefined; - migrateMode = !migrateMode; - }} - > - Migrate Category - </button> - <span style="margin: 0 0.625rem;">•</span> - <button - on:click={() => { - selectedBadge = undefined; - hideMode = !hideMode; - }} - > - Hide Category - </button> - <!-- <!-- <span style="margin: 0 0.625rem;">•</span> --> - <!-- <button on:click={() => exportBadges(groupedBadges)}>Export Badges</button> --> - - {#if shadowHidden} - <span style="margin: 0 0.625rem;">•</span> - <button on:click={setShadowHide}>Un-shadow Hide Badges</button> - {/if} - - {#if editMode && isOwner} - {@const groups = groupedBadges - .map((group) => group[0]) - .filter((group) => group !== 'Uncategorised')} - {@const designers = castAsStringArray([ - ...new Set( - ungroupedBadges - .map((badge) => badge.designer) - .filter((designer) => designer !== undefined && designer !== null) - .filter( - (designer, index, array) => - array.indexOf(designer) === index && !array.includes(`@${designer}`) - ) + {#if editMode && isOwner} + {@const groups = groupedBadges + .map((group) => group[0]) + .filter((group) => group !== 'Uncategorised')} + {@const designers = castAsStringArray([ + ...new Set( + ungroupedBadges + .map((badge) => badge.designer) + .filter((designer) => designer !== undefined && designer !== null) + .filter( + (designer, index, array) => + array.indexOf(designer) === index && !array.includes(`@${designer}`) ) - ])} + ) + ])} - <p /> + <p /> - {#if error} - <p style="color: red;">{error}</p> - {/if} + {#if error} + <p style="color: red;">{error}</p> + {/if} + <input + type="text" + placeholder={$locale().user.badges.editMode.imageURL} + name="image_url" + minlength="1" + maxlength="1000" + size="15" + value={selectedBadge ? selectedBadge.image : ''} + /> + <input + type="text" + placeholder={$locale().user.badges.editMode.activityURL} + name="activity_url" + minlength="1" + maxlength="1000" + size="15" + value={selectedBadge + ? selectedBadge.post === '#' + ? '' + : selectedBadge.post + : ''} + /> + <input + type="text" + placeholder={$locale().user.badges.editMode.description} + name="description" + minlength="1" + maxlength="1000" + size="15" + value={selectedBadge ? selectedBadge.description : ''} + /> + <Dropdown + items={groups.map((group) => ({ + name: group, + url: '#', + onClick: () => { + const category = document.querySelector('input[name="category"]'); + + if (category instanceof HTMLInputElement) category.value = group; + } + }))} + header={false} + center={false} + > + <span slot="title"> <input type="text" - placeholder={$locale().user.badges.editMode.imageURL} - name="image_url" - minlength="1" - maxlength="1000" - size="15" - value={selectedBadge ? selectedBadge.image : ''} - /> - <input - type="text" - placeholder={$locale().user.badges.editMode.activityURL} - name="activity_url" + placeholder={$locale().user.badges.editMode.category} + name="category" minlength="1" maxlength="1000" size="15" value={selectedBadge - ? selectedBadge.post === '#' + ? selectedBadge.category === 'Uncategorised' ? '' - : selectedBadge.post + : selectedBadge.category : ''} + list="categories" /> - <input - type="text" - placeholder={$locale().user.badges.editMode.description} - name="description" - minlength="1" - maxlength="1000" - size="15" - value={selectedBadge ? selectedBadge.description : ''} - /> - <Dropdown - items={groups.map((group) => ({ - name: group, - url: '#', - onClick: () => { - const category = document.querySelector('input[name="category"]'); - - if (category instanceof HTMLInputElement) category.value = group; - } - }))} - header={false} - center={false} - > - <span slot="title"> - <input - type="text" - placeholder={$locale().user.badges.editMode.category} - name="category" - minlength="1" - maxlength="1000" - size="15" - value={selectedBadge - ? selectedBadge.category === 'Uncategorised' - ? '' - : selectedBadge.category - : ''} - list="categories" - /> - </span> - </Dropdown> - <span style="float: right;"> + </span> + </Dropdown> + <span style="float: right;"> + <input + type="datetime-local" + value={selectedBadge && selectedBadge.time + ? dateToInputTime(databaseTimeToDate(selectedBadge.time)) + : ''} + /> + <small>Must be full date and time, defaults to now if any fields empty</small> + </span> + + <p /> + + <div class="edit-row-2"> + <input + type="text" + placeholder={$locale().user.badges.editMode.source} + name="source" + minlength="1" + maxlength="1000" + size="16" + value={selectedBadge ? selectedBadge.source : ''} + /> + <Dropdown + items={designers.map((designer) => ({ + name: designer, + url: '#', + onClick: () => { + const designerField = document.querySelector('input[name="designer"]'); + + if (designerField instanceof HTMLInputElement) + designerField.value = designer; + } + }))} + header={false} + center={false} + > + <span slot="title"> <input - type="datetime-local" - value={selectedBadge && selectedBadge.time - ? dateToInputTime(databaseTimeToDate(selectedBadge.time)) - : ''} + type="text" + placeholder={$locale().user.badges.editMode.designer} + name="designer" + minlength="1" + maxlength="1000" + size="17" + value={selectedBadge ? selectedBadge.designer : ''} /> - <small - >Must be full date and time, defaults to now if any fields empty</small - > </span> - - <p /> - - <div class="edit-row-2"> + </Dropdown> + <Dropdown + items={[false, true].map((hidden) => ({ + name: hidden ? 'Hidden' : 'Shown', + url: '#', + onClick: () => { + const hiddenInput = document.querySelector('input[name="hidden"]'); + + if (hiddenInput instanceof HTMLInputElement) + hiddenInput.value = hidden ? 'Hidden' : 'Shown'; + } + }))} + header={false} + center={false} + > + <span slot="title"> <input type="text" - placeholder={$locale().user.badges.editMode.source} - name="source" + placeholder="Shown" + name="hidden" minlength="1" maxlength="1000" - size="16" - value={selectedBadge ? selectedBadge.source : ''} + size="15" + value={selectedBadge + ? selectedBadge.hidden + ? 'Hidden' + : 'Shown' + : 'Shown'} /> - <Dropdown - items={designers.map((designer) => ({ - name: designer, - url: '#', - onClick: () => { - const designerField = - document.querySelector('input[name="designer"]'); - - if (designerField instanceof HTMLInputElement) - designerField.value = designer; - } - }))} - header={false} - center={false} - > - <span slot="title"> - <input - type="text" - placeholder={$locale().user.badges.editMode.designer} - name="designer" - minlength="1" - maxlength="1000" - size="17" - value={selectedBadge ? selectedBadge.designer : ''} - /> - </span> - </Dropdown> - <Dropdown - items={[false, true].map((hidden) => ({ - name: hidden ? 'Hidden' : 'Shown', - url: '#', - onClick: () => { - const hiddenInput = document.querySelector('input[name="hidden"]'); - - if (hiddenInput instanceof HTMLInputElement) - hiddenInput.value = hidden ? 'Hidden' : 'Shown'; - } - }))} - header={false} - center={false} - > - <span slot="title"> - <input - type="text" - placeholder="Shown" - name="hidden" - minlength="1" - maxlength="1000" - size="15" - value={selectedBadge - ? selectedBadge.hidden - ? 'Hidden' - : 'Shown' - : 'Shown'} - /> - </span> - </Dropdown> - <button class="button-lined" on:click={submitBadge} - >{selectedBadge - ? $locale().user.badges.editMode.update - : $locale().user.badges.editMode.add}</button - > - {#if selectedBadge} - {$locale().user.badges.editMode.or} - <button - class="button-lined" - on:click={() => { - if (selectedBadge) removeBadge(selectedBadge); - }}>{$locale().user.badges.editMode.delete}</button - > - {/if} - </div> + </span> + </Dropdown> + <button class="button-lined" on:click={submitBadge} + >{selectedBadge + ? $locale().user.badges.editMode.update + : $locale().user.badges.editMode.add}</button + > + {#if selectedBadge} + {$locale().user.badges.editMode.or} + <button + class="button-lined" + on:click={() => { + if (selectedBadge) removeBadge(selectedBadge); + }}>{$locale().user.badges.editMode.delete}</button + > {/if} - {/if} - </div> + </div> + {/if} {/if} + </div> + {/if} - <p /> - - <Badges - {ungroupedBadges} - {groupedBadges} - {categoryFilter} - {editMode} - {preferences} - bind:selectedBadge - /> - {/if} - </div> - - {#if isBadgeSelected} - <!-- {@const anyAdjacentBadgeExists = + <p /> + + <Badges + {ungroupedBadges} + {groupedBadges} + {categoryFilter} + {editMode} + {preferences} + bind:selectedBadge + /> + {/if} + </div> + + {#if isBadgeSelected} + <!-- {@const anyAdjacentBadgeExists = adjacentBadgeExists(selectedBadge, ungroupedBadges, -1) || adjacentBadgeExists(selectedBadge, ungroupedBadges, 1)} --> - <Popup - fullscreen - show={isBadgeSelected} - onLeave={() => { - selectedBadge = undefined; - }} - > - <BadgePreview - bind:selectedBadge - onNext={() => setAdjacentCursor(ungroupedBadges, 1)} - onPrevious={() => setAdjacentCursor(ungroupedBadges, -1)} - hasNext={adjacentBadgeExists(selectedBadge, ungroupedBadges, 1) !== undefined} - hasPrevious={adjacentBadgeExists(selectedBadge, ungroupedBadges, -1) !== undefined} - /> - - {#if authorised} - <button on:click={shadowHideBadge}> - {#if selectedBadge && selectedBadge.shadow_hidden} - Un-shadow - {:else} - Shadow - {/if} Hide Badge ({selectedBadge ? selectedBadge.id : 0}) - </button> - {/if} - </Popup> + <Popup + fullscreen + show={isBadgeSelected} + onLeave={() => { + selectedBadge = undefined; + }} + > + <BadgePreview + bind:selectedBadge + onNext={() => setAdjacentCursor(ungroupedBadges, 1)} + onPrevious={() => setAdjacentCursor(ungroupedBadges, -1)} + hasNext={adjacentBadgeExists(selectedBadge, ungroupedBadges, 1) !== undefined} + hasPrevious={adjacentBadgeExists(selectedBadge, ungroupedBadges, -1) !== undefined} + /> + + {#if authorised} + <button on:click={shadowHideBadge}> + {#if selectedBadge && selectedBadge.shadow_hidden} + Un-shadow + {:else} + Shadow + {/if} Hide Badge ({selectedBadge ? selectedBadge.id : 0}) + </button> {/if} - {:catch} - <Popup fullscreen locked>Could not parse badges</Popup> - {/await} - {:else} - <Message message="Loading badges ..." /> - - <Skeleton grid={true} count={100} width="150px" height="170px" /> + </Popup> {/if} - {:catch} - <Popup fullscreen locked>Could not fetch badges</Popup> - {/await} + {/if} {:catch} <AnimeRateLimited>This user's badges could not be loaded.</AnimeRateLimited> {/await} diff --git a/src/routes/user/[user]/badges/+page.ts b/src/routes/user/[user]/badges/+page.ts new file mode 100644 index 00000000..8b7204ad --- /dev/null +++ b/src/routes/user/[user]/badges/+page.ts @@ -0,0 +1,20 @@ +import { load_UserBadges } from '$houdini'; +import { user } from '$lib/Data/AniList/user'; +import type { LoadEvent } from '@sveltejs/kit'; + +export const load = async (event: LoadEvent) => { + const username = event.params.user as string; + const userData = await user(username, /^\d+$/.test(username)); + + return { + ...(await load_UserBadges({ + event, + variables: { + id: userData.id + } + })), + username, + userData, + event + }; +}; |